#include "SymbolModel.h"

#include "LanguageModel.h"
#include <QStyle>
#include <QApplication>

SymbolModel::SymbolModel( QObject * parent ) :
    QAbstractTableModel( parent ),
    symbolTable(),
    currentIndex( 0 ),
    modified( false ),
    currentLanguageModel( 0 )
{
}

QVariant SymbolModel::data( const QModelIndex & index, int role ) const
{
    if( !index.isValid() )
    {
        return QVariant();
    }
    
    if( index.row() >= 0 && index.row() < symbolTable.size() )
    {
        switch( index.column() )
        {
            case 0 :
            {
                if( role == Qt::DisplayRole || role == Qt::EditRole )
                {
                    return symbolTable[ index.row() ].name;
                }
                else if( currentLanguageModel )
                {
                    if( role == Qt::DecorationRole )
                    {
                        if( !currentLanguageModel->rowIsComplete( symbolTable[ index.row() ].index ) )
                        {
                            return QIcon( ":images/warning.png" );
                        }
                    }
                    else if( role == Qt::ToolTipRole )
                    {
                        if( !currentLanguageModel->rowIsComplete( index.row() ) )
                        {
                            return tr( "No translation yet" );
                        }
                    }
                }
            }
            break;
            
            case 1 :
            {
                if( role == Qt::DisplayRole || role == Qt::EditRole )
                {
                    return symbolTable[ index.row() ].index;
                }
            }
            break;
            
            case 2 :
            {
                if( role == Qt::DisplayRole || role == Qt::EditRole )
                {
                    return symbolTable[ index.row() ].isUsed;
                }
            }
            break;
            
            case 3 :
            {
                if( role == Qt::DisplayRole || role == Qt::EditRole )
                {
                    return symbolTable[ index.row() ].comments;
                }
            }
            break;
        }
    }
    
    return QVariant();
}

bool SymbolModel::setData(const QModelIndex &index, const QVariant &value, int role )
{
    if( !index.isValid() )
    {
        return false;
    }
    
    if( index.row() >= 0 && index.row() < symbolTable.size() )
    {
        switch( index.column() )
        {
            case 0 :
            {
                if( role == Qt::EditRole && symbolTable[ index.row() ].name != value.toString() )
                {
                    symbolTable[ index.row() ].name = value.toString();
                    emit dataChanged( index, index );
                    setModified();
                    return true;
                }
            }
            break;
            
            case 1 :
            {
                bool
                    valid;
                int 
                    int_value;
                
                int_value =  value.toInt( &valid );
            
                if( role == Qt::EditRole && valid && symbolTable[ index.row() ].index != int_value )
                {
                    symbolTable[ index.row() ].index = int_value;
                    emit dataChanged( index, index );
                    setModified();
                    return true;
                }
            }
            break;
            
            case 2 :
            {
                bool
                    bool_value;
                
                bool_value =  value.toBool();
            
                if( role == Qt::EditRole && symbolTable[ index.row() ].isUsed != bool_value )
                {
                    
                    symbolTable[ index.row() ].isUsed = bool_value;
                    emit dataChanged( index, index );
                    setModified();
                    return true;
                }
            }
            break;
            
            case 3 :
            {
                if( role == Qt::EditRole && symbolTable[ index.row() ].comments != value.toString() )
                {
                    symbolTable[ index.row() ].comments = value.toString();
                    emit dataChanged( index, index );
                    setModified();
                    return true;
                }
            }
            break;
        }
    }
    
    return false;
}

bool SymbolModel::insertRow ( int row, const QModelIndex & parent )
{
    if( parent.isValid() )
    {
        return false;
    }
    
    beginInsertRows( QModelIndex(), row, row );
    {
    
        Symbol new_symbol;
        
        new_symbol.isUsed = true;
        new_symbol.name = QString("symbol %0").arg( currentIndex );
        new_symbol.index = currentIndex;
        
        ++currentIndex;
        
        symbolTable.insert( row, new_symbol );
    }
    endInsertRows();
    
    setModified();
    
    return true;
}

bool SymbolModel::removeRow ( int row, const QModelIndex & parent )
{
    if( parent.isValid() )
    {
        return false;
    }

    beginRemoveRows( QModelIndex(), row, row );
    {
        symbolTable.remove( row );
    }
    endRemoveRows();
    
    setModified();
    
    return true;
}

void SymbolModel::initializeModel( int index, const QVector<Symbol> & symbol_table )
{
    beginResetModel();
    symbolTable = symbol_table;
    currentIndex = index;
    endResetModel();
}

void SymbolModel::setModified()
{
    if( !modified )
    {
        modified = true;
        emit contentsChanged();
    }
}